package pers.buyusan.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import pers.buyusan.bean.InvokeInfo;

import javax.lang.model.element.VariableElement;
import java.util.*;
import java.util.concurrent.*;

@Activate(group = CommonConstants.CONSUMER)
public class DubbuFilter implements Filter, Runnable {
    private Map<String, CopyOnWriteArrayList<InvokeInfo>> infos = new ConcurrentHashMap<>();


    //第一次调用时启动统计线程
    private boolean b = true;

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        String methodName = invocation.getMethodName();
        long startTime = System.currentTimeMillis();
        Result invoke = invoker.invoke(invocation);
        long endTime = System.currentTimeMillis();
        int time = (int) (endTime - startTime);

        InvokeInfo invokeInfo = new InvokeInfo();
        invokeInfo.setMilliSecond(time);
        invokeInfo.setTime(endTime);
        if (infos.containsKey(methodName)) {
            CopyOnWriteArrayList<InvokeInfo> invokeInfos = infos.get(methodName);
            invokeInfos.add(invokeInfo);
        } else {
            CopyOnWriteArrayList<InvokeInfo> invokeInfos = new CopyOnWriteArrayList<>();
            invokeInfos.add(invokeInfo);
            infos.put(methodName, invokeInfos);
        }
        if (b) {
            b = false;
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(this, 5, 5, TimeUnit.SECONDS);
        }
        return invoke;
    }

    @Override
    public void run() {

        //获取不同方法的list
        Set<String> strings = infos.keySet();
        for (String methodName : strings) {
            CopyOnWriteArrayList<InvokeInfo> invokeInfos = infos.get(methodName);
            //一分钟前的时间戳
            long currentTimeMillis = System.currentTimeMillis() - 1000L;

            //删除一分钟前的数据
            for (int i = invokeInfos.size() - 1; i >= 0; i--) {
                if (invokeInfos.get(i).getTime() < currentTimeMillis) {
                    invokeInfos.remove(i);
                }
            }
            //根据执行时间排序
            Collections.sort(invokeInfos, Comparator.comparingInt(InvokeInfo::getMilliSecond));
            //找到tp90 和 tp99的值
            int tp90Index = (int) (invokeInfos.size() * 0.9);
            int tp99Index = (int) (invokeInfos.size() * 0.99);
            int tp90 = invokeInfos.get(tp90Index - 1).getMilliSecond();
            int tp99 = invokeInfos.get(tp99Index - 1).getMilliSecond();
            System.out.println("方法" + methodName + "的TP90为:" + tp90 + "ms, TP99为：" + tp99 + "ms");

        }

    }

}
